package caralibrobd;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.Scanner;

/**
 *
 * @author pajoer
 */
public final class Utils {

    /**
     * Formato da data "23 de Enero de 2013 a la(s) 23:00".
     */
    public final static String FORMAT_DATE = "dd 'de' MMMM 'de' yyyy 'a la(s)' HH:mm";
    /**
     * Nome do archivo de serialización.
     */
    private final static String NAME_FILE_SERIALIZE = "CaraLibroBD.ser";
    /**
     * Carácter dos subrallados dos menús.
     */
    public final static String CHAR = "═";
    /**
     *
     */
    public final static String CHAR_ = "─";
    /**
     *
     */
    public final static boolean ASC = true;
    /**
     *
     */
    public final static boolean DES = false;

    /**
     * Método para a entrada dos números por teclado.
     * <p/>
     * @return O valor numérico introducido.
     */
    public static int pulsaTecla() {
        Scanner entrada = new Scanner(System.in);
        try {
            return Integer.parseInt(entrada.nextLine());
        } catch (NumberFormatException ex) {
            return -1;
        }
    }

    /**
     * Método que devolve unha cadea según sexa o autor ou non.
     * <p/>
     * @param pa perfilActivo
     * @param autor nome que se compara co nome do perfil activo.
     * @return Cadea de texto según sexas ou non o autor do texto.
     */
    public static String quenEscribiu(Perfil pa, String autor) {
        return (autor.equals(pa.getNome())
                ? "ti escribiches:" : autor + " escribiu:");
    }

    /**
     *
     * @param d Fecha a dar formato
     * @return A data formateada según criterio definido en FORMAT_DATE
     */
    public static String getFormatoData(Date d) {
        SimpleDateFormat f = new SimpleDateFormat(FORMAT_DATE);
        return f.format(d);
    }

    /**
     * Mostra por pantalla un aviso de confirmación.
     *
     * @param texto Descripción que se mostra por pantalla.
     * @return Un valor booleano true se se resposta S.
     */
    public static boolean pedirConfirmacion(String texto) {
        try {
            Scanner entrada = new Scanner(System.in);
            int n = texto.length();
            System.err.println(repetirCadea(CHAR, n));
            System.err.print(texto + " S/N : ");
            return ("S".equals(entrada.nextLine().toUpperCase()));
        } catch (InputMismatchException e) {
            return false;
        }
    }

    /**
     * Mostra un aviso por pantalla.
     * <p/>
     * @param texto a mostrar no aviso.
     */
    public static void printAviso(String texto) {
        if (texto != null) {
            int n = texto.length() + 2;
            vaciarBuffers();
            System.out.println("\n╔" + repetirCadea(CHAR, n) + "╗");
            System.out.println("║ " + texto + " ║");
            System.out.println("╚" + repetirCadea(CHAR, n) + "╝\n");
        }
    }

    /**
     * Mostra en vermello un aviso ou fallo.
     * <p/>
     * @param texto  a mostrar no aviso
     * @param accion
     */
    public static void printAvisoErro(String texto, String accion) {
        if (texto != null) {
            int n = texto.length() + 2;
            int a = accion.length() + 2;
            vaciarBuffers();
            System.err.println("\n╓" + repetirCadea(CHAR_, a) + "╥" + repetirCadea(CHAR_, n) + "╖");
            System.err.println("║ " + accion + " ║ " + texto + " ║");
            System.err.println("╙" + repetirCadea(CHAR_, a) + "╨" + repetirCadea(CHAR_, n) + "╜\n");
        }
    }

    /**
     * Forza os buffers de impresión por pantalla a que escriban.
     *
     */
    public static void vaciarBuffers() {
        System.err.flush();
        System.out.flush();
        gardarDatos();
    }

    /**
     *
     */
    public static void limparPantalla() {
        System.out.println(repetirCadea("\n\n", 50));
    }

    /**
     * Repite unha cadea de caracteres n veces.
     * <p/>
     * @param s A cadea a repetir.
     * @param n O número de veces a repetila.
     * @return
     */
    public static String repetirCadea(String s, int n) {
        // Función recursiva e optimizada para facer o mínimo de interacións.
        if (n <= 0) { // Si é 0 ou menos devolve "" empty.
            return "";
        } else if (n % 2 == 0) { // Se n é par sumamoslle outra cadea igual e dividimos n/2.
            return repetirCadea(s + s, n / 2);
        } else { // Se é impar, sumasmolle unha diante para facela par e tratamola como se fora par.
            return s + repetirCadea(s + s, n / 2);
        }
    }

    /**
     * Limpia todos los datos.
     */
    public static void limparDatos() {
        // HashMap<String, Perfil> hmPerfiles
        //CaraLibroBD.getPerfiles()
        if (CaraLibroBD.getPerfiles() != null) {
            CaraLibroBD.getPerfiles().clear();
            gardarDatos();
        }
    }

    /**
     * Guarda los datos.
     */
    public static void gardarDatos() {
        Serializador.serializeObject(NAME_FILE_SERIALIZE, CaraLibroBD.getPerfiles());
    }

    /**
     *
     */
    public static void lerDatos() {
        try {
            CaraLibroBD.setPerfiles((HashMap<String, Perfil>) Serializador.deSerializeObject(NAME_FILE_SERIALIZE));
        } catch (NullPointerException ex) {
            printAvisoErro("Erro!!!", ex.getMessage());
        }

    }

    /**
     *
     * @param m
     * @param order
     * @return
     */
    public static ArrayList sortByValueComentario(final HashMap m, final boolean order) {
        ArrayList keys = new ArrayList();
        keys.addAll(m.keySet());
        Collections.sort(keys, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Comentario v1 = (Comentario) m.get((order) ? o1 : o2);
                Comentario v2 = (Comentario) m.get((order) ? o2 : o1);
                if (v1.getData() == null) {
                    return (v2.getData() == null) ? 0 : 1;
                } else if (v1.getData() instanceof Date) {
                    return (v1.getData().compareTo(v2.getData()));
                } else {
                    return 0;
                }
            }

        });
        return keys;
    }

    /**
     *
     * @param m
     * @param order
     * @return
     */
    public static ArrayList sortByValuePublicacion(final HashMap m, final boolean order) {
        ArrayList keys = new ArrayList();
        keys.addAll(m.keySet());
        Collections.sort(keys, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Publicacion v1 = (Publicacion) m.get((order) ? o1 : o2);
                Publicacion v2 = (Publicacion) m.get((order) ? o2 : o1);
                if (v1.getData() == null) {
                    return (v2.getData() == null) ? 0 : 1;
                } else if (v1.getData() instanceof Date) {
                    return (v1.getData().compareTo(v2.getData()));
                } else {
                    return 0;
                }
            }

        });
        return keys;
    }

    /**
     *
     * @param m
     * @param order
     * @return
     */
    public static ArrayList sortByValueEvento(final HashMap m, final boolean order) {
        ArrayList keys = new ArrayList();
        keys.addAll(m.keySet());
        Collections.sort(keys, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Evento v1 = (Evento) m.get((order) ? o1 : o2);
                Evento v2 = (Evento) m.get((order) ? o2 : o1);
                if (v1.getData() == null) {
                    return (v2.getData() == null) ? 0 : 1;
                } else if (v1.getData() instanceof Date) {
                    return (v1.getData().compareTo(v2.getData()));
                } else {
                    return 0;
                }
            }

        });
        return keys;
    }

    /**
     *
     * @param m
     * @param order
     * @return
     */
    public static ArrayList sortByValueMensaxe(final HashMap m, final boolean order) {
        ArrayList keys = new ArrayList();
        keys.addAll(m.keySet());
        Collections.sort(keys, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Mensaxe v1 = (Mensaxe) m.get((order) ? o1 : o2);
                Mensaxe v2 = (Mensaxe) m.get((order) ? o2 : o1);
                String key1 = ((v1.isLido()) ? "0" : "1") + String.valueOf(v1.getData().getTime());
                String key2 = ((v2.isLido()) ? "0" : "1") + String.valueOf(v2.getData().getTime());
                if (key1 == null) {
                    return (key2 == null) ? 0 : 1;
                } else if (key1 instanceof String) {
                    return (key1.compareTo(key2));
                } else {
                    return 0;
                }
            }

        });
        return keys;
    }
}
